﻿namespace eBdb.EpubReader.Collections.Generic
{
    using System;
    using System.Linq;
    using System.Collections;
    using System.Collections.Generic;

    public class HashSet<T> : ISet<T>
    {
        List<T> items;
        IEqualityComparer<T> comparer;

        public HashSet()
        {
            items = new List<T>();
        }

        public HashSet(IEnumerable<T> collection)
        {
            items = new List<T>(collection);
        }

        public HashSet(IEqualityComparer<T> comparer)
        {
            items = new List<T>();
            this.comparer = comparer;
        }

        public bool Add(T item)
        {
            if (Contains(item))
            {
                return false;
            }

            items.Add(item);
            return true;
        }

        public void ExceptWith(IEnumerable<T> other)
        {
            List<T> otheritems = new List<T>(other);

            for (int i = 0; i < items.Count; i++)
            {
                if (otheritems.Contains(items[i]) ||
                    (this.comparer != null && otheritems.Contains(items[i], this.comparer)))
                {
                    items.RemoveAt(i);
                    i--;
                }
            }
        }

        public void IntersectWith(IEnumerable<T> other)
        {
            throw new NotImplementedException();
        }

        public bool IsProperSubsetOf(IEnumerable<T> other)
        {
            throw new NotImplementedException();
        }

        public bool IsProperSupersetOf(IEnumerable<T> other)
        {
            throw new NotImplementedException();
        }

        public bool IsSubsetOf(IEnumerable<T> other)
        {
            throw new NotImplementedException();
        }

        public bool IsSupersetOf(IEnumerable<T> other)
        {
            throw new NotImplementedException();
        }

        public bool Overlaps(IEnumerable<T> other)
        {
            throw new NotImplementedException();
        }

        public bool SetEquals(IEnumerable<T> other)
        {
            throw new NotImplementedException();
        }

        public void SymmetricExceptWith(IEnumerable<T> other)
        {
            throw new NotImplementedException();
        }

        public void UnionWith(IEnumerable<T> other)
        {
            this.items = this.items.Union(other).ToList();
        }

        void ICollection<T>.Add(T item)
        {
            this.items.Add(item);
        }

        public void Clear()
        {
            this.items.Clear();
        }

        public bool Contains(T item)
        {
            if (comparer != null)
            {
                return items.Contains(item, comparer);
            }

            return items.Contains(item);
        }

        public void CopyTo(T[] array, int arrayIndex)
        {
            this.items.CopyTo(array, arrayIndex);
        }

        public int Count
        {
            get { return this.items.Count; }
        }

        public bool IsReadOnly
        {
            get { return false; }
        }

        public bool Remove(T item)
        {
            return this.items.Remove(item);
        }

        public IEnumerator<T> GetEnumerator()
        {
            return this.items.GetEnumerator();
        }

        IEnumerator IEnumerable.GetEnumerator()
        {
            return GetEnumerator();
        }
    }
}
